﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Casamiel.API.Application;
using Casamiel.API.Infrastructure;
using Casamiel.Common;
using Casamiel.Common.Utilities;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace Casamiel.API.Controllers.V2
{
    /// <summary>
    ///测试环境
    /// Da da controller.
    /// </summary>
    [Produces("application/json")]
    [ApiVersion("2.0")]
    [Route("api/v{api-version:apiVersion}/[controller]")]
    [ApiController]
    public class DaDaController : Controller
    {
        private readonly ICacheService _cacheService;
        private readonly string appkey = "dada527645c5c5b839e";
        private readonly string app_secret = "846a2828869f8decabdb9beb17316d0d";
        private readonly string source_id = "73753";
        private readonly string apiUrl = "";
        private readonly NLog.ILogger logger = LogManager.GetLogger("OrderService");
        private readonly IStoreApiService _storeApiService;
        private readonly string _apitoken;
        private readonly string _contact_name;
        private readonly string _phone;
        private readonly string _store_pre;
        private readonly string _business;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="setting"></param>
        /// <param name="snapshot"></param>
        /// <param name="storeApiService"></param>
        /// <param name="cacheService"></param>
        public DaDaController(IOptionsSnapshot<DaDaSettings> setting, IOptionsSnapshot<CasamielSettings> snapshot, IStoreApiService storeApiService, ICacheService cacheService)
        {
            if (setting == null)
            {
                throw new ArgumentNullException(nameof(setting));
            }

            if (snapshot == null)
            {
                throw new ArgumentNullException(nameof(snapshot));
            }

            _storeApiService = storeApiService;
            _cacheService = cacheService;
            appkey = setting.Value.appkey;
            app_secret = setting.Value.app_secret;
            _business = setting.Value.Business;
            source_id = setting.Value.source_id;
            apiUrl = setting.Value.apiurl;
            _apitoken = snapshot.Value.ApiToken;
            _contact_name = setting.Value.contact_name;
            _phone = setting.Value.phone;
            _store_pre = setting.Value.store_pre;
        }


        /// <summary>
        /// Gets the order cancel reasons.
        /// </summary>
        /// <returns>The order cancel reasons.</returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> getOrderCancelReasons()
        {
            var url = "/api/order/cancel/reasons";
            var result = await PostAsync("", url).ConfigureAwait(false);
            return Ok(JsonConvert.DeserializeObject<JObject>(result));
        }
        /// <summary>
        /// Formals the cancel.
        /// http://newopen.imdada.cn/#/development/file/formalCancel?_k=4l1784
        /// </summary>
        /// <returns>The cancel.</returns>
        /// <param name="data">Data.</param>
        /// <remarks>{"order_id":"","cancel_reason_id":1,"cancel_reason":""}</remarks>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> FormalCancel([FromBody]JObject data)
        {
            var url = "/api/order/formalCancel";
            var result = await PostAsync(JsonConvert.SerializeObject(data), url).ConfigureAwait(false);
            return Ok(JsonConvert.DeserializeObject<JObject>(result));
        }
        /// <summary>
        /// Adds the order.
        /// </summary>
        /// <returns>The order.</returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> AddOrder()
        {
            var data = new
            {
                shop_no = 73753,
                origin_id = "O3993939399911",
                city_code = "0571",
                info = "测试订单",
                cargo_price = 10.5,
                is_prepay = 0,
                expected_fetch_time = 1471536000,
                receiver_name = "测试",
                receiver_address = "上海市崇明岛",
                receiver_phone = "1858888888",
                receiver_tel = "18599999999",
                receiver_lat = 31.63,
                receiver_lng = 121.41,
                callback = "https://apitest.casamiel.cn/api/v2/dada/callback"
            };


            //Dictionary<String, String> bizContent = new Dictionary<string, string>();
            //bizContent.Add("app_key", appkey);
            //bizContent.Add("body", JsonConvert.SerializeObject(data));
            //bizContent.Add("format", "json");
            //bizContent.Add("v", "1.0");
            //bizContent.Add("source_id", source_id);
            //bizContent.Add("timestamp", DatetimeUtil.GetUnixTime(DateTime.Now).ToString());
            //bizContent.Add("signature", encryptAndSign(bizContent).ToUpper());

            var result = await PostAsync(JsonConvert.SerializeObject(data), "/api/order/addOrder").ConfigureAwait(false);
            return Ok(JsonConvert.DeserializeObject<JObject>(result));
            //var client = new HttpClient();
            //var requestMessage = new HttpRequestMessage(HttpMethod.Post, "http://newopen.qa.imdada.cn/api/order/addOrder");
            //requestMessage.Content = new StringContent(JsonConvert.SerializeObject(bizContent), System.Text.Encoding.UTF8, "application/json");

            //var response = await client.SendAsync(requestMessage);
            //if (response.IsSuccessStatusCode)
            //{
            //    var result = await response.Content.ReadAsStringAsync();
            //    return Ok(new { status = "success", code = 0, content = result });
            //}
            //return Ok(new { status = "success", code = 0,content=JsonConvert.SerializeObject(bizContent) });
        }
        private async Task<string> PostAsync(string content, string url)
        {
            Dictionary<String, String> bizContent = new Dictionary<string, string>
            {
                { "app_key", appkey },
                { "body", content },
                { "format", "json" },
                { "v", "1.0" },
                { "source_id", source_id },
                { "timestamp", DatetimeUtil.GetUnixTime(DateTime.Now).ToString(CultureInfo.CurrentCulture) }
            };
            bizContent.Add("signature", encryptAndSign(bizContent).ToUpper( CultureInfo.CurrentCulture));
            var client = new HttpClient
            {
                BaseAddress = new Uri(apiUrl)
            };
            //client.DefaultRequestHeaders.Add("Content-Type", "application/json");
            var requestMessage = new HttpRequestMessage(HttpMethod.Post, $"{url}")
            {
                // requestMessage.Headers.Add("Content-Type", "application/json");
                Content = new StringContent(JsonConvert.SerializeObject(bizContent), System.Text.Encoding.UTF8, "application/json")
            };
            try
            {
                var response = await client.SendAsync(requestMessage).ConfigureAwait(false);
                if (response.IsSuccessStatusCode)
                {
                    var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                    return result;
                }
                else
                {
                    return JsonConvert.SerializeObject(new { msg = response.StatusCode });
                }
            }
            catch (HttpRequestException ex)
            {
                return JsonConvert.SerializeObject(new { msg = ex.Message });
            }
        }
        private string encryptAndSign(Dictionary<string, string> dic)
        {
            // 第一步：把字典按Key的字母顺序排序
            IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(dic);

            // 第二步：把所有参数名和参数值串在一起，生成json格式
            //string content = JsonConvert.SerializeObject(sortedParams);
            string content = "";
            foreach (var item in sortedParams)
            {
                content = content + item.Key + item.Value;
            }
            content = Sign(content, app_secret, app_secret);
            return content;
        }
        /// <summary>
        /// 签名字符串
        /// </summary>
        /// <param name="prestr">需要签名的字符串</param>
        /// <param name="keyPre">密钥：前置密钥</param>
        /// <param name="keyAfter">密钥：后置密钥</param>
        /// <param name="_input_charset">编码格式</param>
        /// <returns>签名结果</returns>
        private string Sign(string prestr, string keyPre, string keyAfter, string _input_charset = "utf-8")
        {
            StringBuilder sb = new StringBuilder(32);

            prestr = keyPre + prestr + keyAfter;

            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] t = md5.ComputeHash(Encoding.GetEncoding(_input_charset).GetBytes(prestr));
            for (int i = 0; i < t.Length; i++)
            {
                sb.Append(t[i].ToString("x").PadLeft(2, '0'));
            }
            return sb.ToString();
        }

        /// <summary>
        /// Adds the shop.
        /// </summary>
        /// <returns>The shop.</returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> BathAddShop([FromHeader(Name = "u-token")] string token)
        {
            if (token != _apitoken)
            {
                Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                return Ok(new { code = 99999, msg = "token无效" });
            }
            var url = "/api/shop/add";

            var data = await _storeApiService.GetShopListForDada().ConfigureAwait(false);
            var list = JsonConvert.DeserializeObject<List<Dadashop>>(data);
            list.ForEach(x =>
            {
                x.business = _business;
                x.station_name = _store_pre + x.station_name;
                if (!string.IsNullOrEmpty(_contact_name))
                {
                    x.contact_name = _contact_name;
                }
                if (!string.IsNullOrEmpty(_phone))
                {
                    x.phone = _phone;
                }
            });
            var result = await PostAsync(JsonConvert.SerializeObject(list), url).ConfigureAwait(false);
            return Ok(JsonConvert.DeserializeObject<JObject>(result));
        }
        /// <summary>
        /// Baths the add shop.
        /// </summary>
        /// <returns>The add shop.</returns>
        /// <param name="data">Data.</param>
        /// <param name="token">Token.</param>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> AddShop([FromBody]string data, [FromHeader(Name = "u-token")] string token)
        {
            if (token != _apitoken)
            {
                Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                return Ok(new { code = 99999, msg = "token无效" });
            }
            var url = "/api/shop/add";
            var result = await PostAsync(data, url).ConfigureAwait(false);
            return Ok(JsonConvert.DeserializeObject<JObject>(result));
        }
        /// <summary>
        /// Updates the shop.
        /// </summary>
        /// <returns>The shop.</returns>
        /// <param name="data">Data.</param>
        /// <param name="token">Token.</param>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> UpdateShop([FromBody]JObject data, [FromHeader(Name = "u-token")] string token)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            if (!token.Equals(_apitoken))
            {
                Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                return Ok(new { code = 99999, msg = "token无效" });
            }

            var url = "/api/shop/update";
            var result = await PostAsync(JsonConvert.SerializeObject(data), url).ConfigureAwait(false);
            return Ok(JsonConvert.DeserializeObject<JObject>(result));
        }
        /// <summary>
        /// Batchs the update shop.
        /// </summary>
        /// <returns>The update shop.</returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> BatchUpdateShop([FromHeader(Name = "u-token")] string token)
        {
            if (token != _apitoken)
            {
                Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                return Ok(new { code = 99999, msg = "token无效" });
            }
            var url = "/api/shop/update";
            var data = await _storeApiService.GetShopListForDada().ConfigureAwait(false);
            var list = JsonConvert.DeserializeObject<List<Dadashop>>(data);

            var resultlist = new List<string>();
            list.ForEach(async x =>
            {
                x.business = _business;
                x.station_name = _store_pre + x.station_name;
                if (!string.IsNullOrEmpty(_contact_name))
                {
                    x.contact_name = _contact_name;
                }
                if (!string.IsNullOrEmpty(_phone))
                {
                    x.phone = _phone;
                }
                var result = await PostAsync(JsonConvert.SerializeObject(x), url).ConfigureAwait(false);
                resultlist.Add(result);
            });

            return Ok(resultlist);
        }
    }
    /// <summary>
    /// Dadashop.
    /// </summary>
    public class Dadashop
    {
        //{"station_name":"工厂店","business":20,"city_name":"杭州","area_name":"余杭区","station_address":"下沙经济开发区3号大街201号4幢","lng":120.33962249755859,"lat":30.287771224975586,"contact_name":"廖文东","phone":"0571-88114785","origin_shop_id":222105
        /// <summary>
        /// Gets or sets the origin shop identifier.
        /// </summary>
        /// <value>The origin shop identifier.</value>
        public string origin_shop_id { get; set; }
        /// <summary>
        /// Gets or sets the name of the station.
        /// </summary>
        /// <value>The name of the station.</value>
        public string station_name { get; set; }
        /// <summary>
        /// Gets or sets the name of the city.
        /// </summary>
        /// <value>The name of the city.</value>
        public string city_name { get; set; }
        /// <summary>
        /// Gets or sets the name of the area.
        /// </summary>
        /// <value>The name of the area.</value>
        public string area_name { get; set; }
        /// <summary>
        /// Gets or sets the station address.
        /// </summary>
        /// <value>The station address.</value>
        public string station_address { get; set; }
        /// <summary>
        /// Gets or sets the lng.
        /// </summary>
        /// <value>The lng.</value>
        public double lng { get; set; }
        /// <summary>
        /// Gets or sets the lat.
        /// </summary>
        /// <value>The lat.</value>
        public double lat { get; set; }
        /// <summary>
        /// Gets or sets the name of the contact.
        /// </summary>
        /// <value>The name of the contact.</value>
        public string contact_name { get; set; }
        /// <summary>
        /// Gets or sets the phone.
        /// </summary>
        /// <value>The phone.</value>
        public string phone { get; set; }
        /// <summary>
        /// Gets or sets the business.
        /// </summary>
        /// <value>The business.</value>
        public string business { get; set; }
    }
}
